﻿using System.IO.Ports;
using System.Text;

namespace SerialPort通讯
{
    internal class Program
    {
        static void Main(string[] args)
        {
            {
                #region 查询当前机器上所有可用串口
                string[] portNames = SerialPort.GetPortNames();
                foreach (string portName in portNames)
                {
                    Console.WriteLine(portName);
                }
                #endregion

                #region 实例化串口对象
                SerialPort serialPort = new SerialPort();
                #endregion

                #region 串口基本参数设置
                serialPort.PortName = "COM1";           // 串口名称
                serialPort.BaudRate = 9600;             // 波特率：每秒发送比特位个数
                serialPort.Parity = Parity.None;        // 校验位：用1个比特位校验确保数据位和校验位中“1”的总个数是奇数或者偶数（存在误判）
                serialPort.DataBits = 8;                // 数据位：用于表示有效数据的比特位个数
                serialPort.StopBits = StopBits.One;     // 停止位：固定为“1”的1比特位，以接收1bit的时间为基准来设置的时间间隔，可以为0.5、1、1.5、2
                #endregion

                #region 串口输入输出相关参数设置
                serialPort.ReadTimeout = 5000;          // 读取超时时间：在ReadTimeout时间内，读取数据的读取数据量未达到预期（程序<-内核），则读取超时
                serialPort.WriteTimeout = 5000;         // 发送超时时间：在WriteTimeout时间内，发送数据的写入数据量未达到预期（程序->内核），则发送超时
                serialPort.ReadBufferSize = 4096;       // 接受缓冲区大小（接收缓冲区已内置）
                serialPort.WriteBufferSize = 2048;      // 发送缓冲区大小
                #endregion

                #region 串口的打开和关闭
                serialPort.Open();
                if (serialPort.IsOpen) Console.WriteLine(serialPort.PortName + "已打开");
                // if (serialPort.IsOpen) serialPort.Open(); // 串口独占，不可再次打开
                serialPort.Close();
                #endregion
            }
            #region 串口的发送与接受
            using (SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One))
            {
                try
                {
                    // 打开串口
                    serialPort.Open();

                    // 发送数据
                    // - Write 发送字符串
                    serialPort.WriteLine("Hello, Serial Port!");
                    // - Write 发送字节数组
                    byte[] bytes = Encoding.UTF8.GetBytes("abc123中文");
                    serialPort.Write(bytes, 0, bytes.Length);

                    // 接收数据
                    serialPort.ReadTimeout = 10000;
                    // - ReadExisting 非阻塞读
                    {
                        string received = serialPort.ReadExisting();
                        Console.WriteLine("Received (ReadExisting): " + received);
                    }
                    // - Read 阻塞读
                    {
                        byte[] rec = new byte[20]; // 根据缓冲区实际字节数创建数组
                        int bytesRead = serialPort.Read(rec, 0, rec.Length); // 2025年6月22日 这个接口会因为某些我目前不清楚的情况读了第一个字节之后忽略可读数据不进行读取了
                        if (bytesRead > 0)
                        {
                            string received = Encoding.UTF8.GetString(rec, 0, bytesRead);
                            Console.WriteLine("Received (Read): " + received);
                        }
                    }
                    // - ReadByte 按字节读
                    {
                        int byteRead = serialPort.ReadByte();
                        if (byteRead != -1)
                        {
                            Console.WriteLine("Received (ReadByte): " + byteRead);
                        }
                    }
                    // - ReadChar 按字符读
                    {
                        int charRead = serialPort.ReadChar();
                        if (charRead != -1)
                        {
                            char c = (char)charRead;
                            Console.WriteLine("Received (ReadChar): " + c.ToString());
                        }
                    }
                    // - ReadLine 读取数据直到遇到换行
                    {
                        serialPort.NewLine = "@"; // 设置行结束符
                        string line = serialPort.ReadLine();
                        if (line != null)
                        {
                            Console.WriteLine("Received (ReadLine): " + line);
                        }
                    }
                    // - ReadTo 读直到遇到某个字符串
                    {
                        string line = serialPort.ReadTo("@");
                        if (line != null)
                        {
                            Console.WriteLine("Received (ReadTo): " + line);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.Message);
                }
            }
            #endregion
        }
    }
}
